package com.qf.smsplatform.strategy.service.impl;

import com.qf.smsplatform.common.constants.CacheConstants;
import com.qf.smsplatform.common.constants.StrategyConstants;
import com.qf.smsplatform.common.model.StandardSubmit;
import com.qf.smsplatform.strategy.service.Strategy;
import com.qf.smsplatform.strategy.service.api.CacheService;
import com.qf.smsplatform.strategy.util.PushMsgUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 扣费策略
 */
@Service(value = "fee")
@Slf4j
public class FeeStrategy implements Strategy {

    @Autowired
    private CacheService cacheService;

    @Autowired
    private PushMsgUtil pushMsgUtil;


    @Override
    public boolean strategy(StandardSubmit submit) {
        log.info("【策略模块】 扣费策略开始执行！！！");
        // 类似将指定的金额,冻结起来(预扣费)
        //1. 查询当前客户存储在缓存模块中的剩余费用
        Long fee = Long.parseLong(cacheService.hget(CacheConstants.CACHE_PREFIX_CLIENT + submit.getClientID(), "fee"));

        //2. 查询当前短信需要的费用
        Long messageFee = submit.getFee();

        //3. 判断客户 剩余费用 >= 短信需要的费用
        if(fee >= messageFee) {
            //4. 满足要求,开始扣费(incr)
            Long surplusFee = cacheService.hincr(CacheConstants.CACHE_PREFIX_CLIENT + submit.getClientID(), "fee", -messageFee);

            //5. 扣费完成之后,用户的剩余金额 < 0
            if(surplusFee < 0) {
                //6. 如果扣除后,金额 < 0  -- 用户金额不足,将扣除的费用再加回缓存,记录日志,发送消息,return false
                log.info("【策略模块】 扣费策略执行失败。。。用户剩余金额不足。。。");
                cacheService.hincr(CacheConstants.CACHE_PREFIX_CLIENT + submit.getClientID(), "fee", messageFee);
                pushMsgUtil.sendLog(submit, StrategyConstants.STRATEGY_ERROR_FEE);
                pushMsgUtil.pushReport(submit, StrategyConstants.STRATEGY_ERROR_FEE);
                return false;
            }
            //7. 如果可以成功发送,记录预扣除的费用.(冻结的费用)   冻结费用的key, CUSTOMER_FEE:  拼接上客户的ID
            cacheService.incr(CacheConstants.CACHE_PREFIX_CUSTOMER_FEE + submit.getClientID(),messageFee);
            // 冻结费用成功，记录日志，return true
            log.info("【策略模块】 扣费策略执行成功！！！");
            return true;
        }
        // 如果第一个if没进去,说明用户剩余金额不足
        log.info("【策略模块】 扣费策略执行失败。。。用户剩余金额不足。。。");
        pushMsgUtil.sendLog(submit, StrategyConstants.STRATEGY_ERROR_FEE);
        pushMsgUtil.pushReport(submit, StrategyConstants.STRATEGY_ERROR_FEE);
        return false;

    }
}
